//定义游戏需要的数据。

//单元格宽度，以像素为单位
var grid = 16;
// 蛇
var snake;
// 食物
var food;
// 计时器
var timer = null;

//定义函数

// 在min到max的范围内取随机数。
function getRandomInt(min, max) {
    return Math.floor(Math.random() * (max - min)) + min;
}

// 重新开始游戏
function startGame() {

    snake = {
        // 初始位置
        x: 160,
        y: 160,
        // 移动速度和方向
        dx: grid,
        dy: 0,
        // 长度
        maxCells: 4,
        // 各个节点的坐标
        cells: []
    };

    food = {
        x: getRandomInt(0, 25) * grid,
        y: getRandomInt(0, 25) * grid
    };

    // 如果计时器删除了，重新创建，如果没有删除，继续使用原有的。
    if (timer == null) {
        timer = setInterval(loop, 1000 / 15);
    }
}

// Game Over
function gameOver() {
    // 删除计时器
    clearInterval(timer);
    timer = null;

    // 清理画布
    context.clearRect(0, 0, canvas.width, canvas.height);

    // 设置字体、对齐方式和颜色
    context.font = "30px Arial";
    context.textAlign = "center";
    context.fillStyle = 'blue';
    // 显示 GAME OVER
    context.fillText("GAME OVER", canvas.width / 2, canvas.height / 2);
}

// 程序主循环
function loop() {

    // 清理画布
    context.clearRect(0, 0, canvas.width, canvas.height);

    // 蛇移动

    // 计算新的节点的坐标。
    snake.x += snake.dx;
    snake.y += snake.dy;
    // 增加到头头部
    snake.cells.unshift({
        x: snake.x,
        y: snake.y
    });
    // 如果maxCells没有增加，也就是没有生长，尾部节点就会被删除
    if (snake.cells.length > snake.maxCells) {
        snake.cells.pop();
    }

    // 判断蛇吃到食物
    if (snake.x === food.x && snake.y === food.y) {
        // 生长
        snake.maxCells += 4; //每次长4个节点
        // 生成新的食物
        food.x = getRandomInt(0, 25) * grid;
        food.y = getRandomInt(0, 25) * grid;
    }

    // 判断是否撞墙
    if (snake.x < 0 || snake.x >= canvas.width || snake.y < 0 || snake.y >= canvas.height) {
        gameOver();
        return;
    }

    // 判断是否有和自己碰撞的情况
    for (var i = 1; i < snake.cells.length; i++) {
        if (snake.cells[i].x === snake.x && snake.cells[i].y === snake.y) {
            gameOver();
            return;
        }
    }

    // 绘制食物
    context.fillStyle = 'red';
    context.fillRect(food.x, food.y, grid - 1, grid - 1);

    // 绘制蛇
    context.fillStyle = 'green';
    // 画每一个节点，节点间有1个像素的间隙
    for (var i = 0; i < snake.cells.length; i++) {
        context.fillRect(snake.cells[i].x, snake.cells[i].y, grid - 1, grid - 1);
    };
}

// 处理键盘按键
function onKeyDown(keyEvent) {

    // enter键，重启游戏。
    if (keyEvent.key == "Enter") {
        startGame()
    }
    // 上下左右键，改变蛇的方向，但不能掉头
    // left arrow key
    else if (keyEvent.key == "ArrowLeft" && snake.dx == 0) {
        snake.dx = -grid;
        snake.dy = 0;
    }
    // up arrow key
    else if (keyEvent.key == "ArrowUp" && snake.dy == 0) {
        snake.dy = -grid;
        snake.dx = 0;
    }
    // right arrow key
    else if (keyEvent.key == "ArrowRight" && snake.dx == 0) {
        snake.dx = grid;
        snake.dy = 0;
    }
    // down arrow key
    else if (keyEvent.key == "ArrowDown" && snake.dy == 0) {
        snake.dy = grid;
        snake.dx = 0;
    }
}

// 获得画布对象和上下文
var canvas = document.getElementById('game');
var context = canvas.getContext('2d');

// 设置键盘监听
document.addEventListener('keydown', onKeyDown);

// 游戏开始
startGame();
